
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.Practices.WizardFramework;
using System.Collections;
using System.Configuration;
using Microsoft.Practices.RepositoryFactory.CustomPages.Helpers;
using Microsoft.Practices.RepositoryFactory.CustomPages.UI;
using System.ComponentModel.Design;
using System.Windows.Forms.Design;
using SD = Microsoft.Practices.RepositoryFactory.SchemaDiscovery.ObjectModel.Base;
using Microsoft.Practices.RepositoryFactory.CustomPages.Validators;
using Microsoft.Practices.RepositoryFactory.SchemaDiscovery.ObjectModel.Base;

namespace Microsoft.Practices.RepositoryFactory.CustomPages
{
    public partial class SPTablesSelectorCP : CustomWizardPage
    {
        #region Fields
        private ArrayList tables;
        string cnstring;
        #endregion

        #region Constructors
        public SPTablesSelectorCP(WizardForm parent)
            : base(parent)
        {
            InitializeComponent();
        }
        #endregion

        #region Arguments
        [RecipeArgument]
        public ArrayList Tables
        {
            get
            {
                return this.tables;
            }
            set
            {
                this.tables = value;
            }
        }
        #endregion

        #region Event Handlers
        private void trvDatabase_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            if(e.Node is TableNode)
            {
                if(!new TableValidator((Table)e.Node.Tag).IsValid())
                {
                    e.Cancel = true;
                    return;
                }
            }
        }

        private void trvDatabase_BeforeCheck(object sender, TreeViewCancelEventArgs e)
        {
            if(e.Node is TableNode)
            {
                if(!new TableValidator((Table)e.Node.Tag).IsValid())
                {
                    e.Cancel = true;
                    return;
                }
            }
        }

        private void trvDatabase_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if(e.Action == TreeViewAction.ByMouse || e.Action == TreeViewAction.ByKeyboard)
            {
                NodesHelper.VerifyParent(e);
                NodesHelper.CheckNodes(e.Node, e.Node.Checked);
            }
            else
            {
                NodesHelper.VerifyParent(e);
            }
        }

        public override void OnActivated()
        {
            IDictionaryService dictservice = (IDictionaryService)GetService(typeof(IDictionaryService));
            ConnectionStringSettings connectionSettings = (ConnectionStringSettings)dictservice.GetValue("ConnectionSettings");

            if(dictservice.GetValue("Tables") == null)
            {
                //First Time
                RenderNodes();
                cnstring = connectionSettings.ConnectionString;
            }
            else
            {
                if(cnstring != connectionSettings.ConnectionString)
                {
                    //ConnectionString changed
                    RenderNodes();
                    cnstring = connectionSettings.ConnectionString;
                    dictservice.SetValue("Tables", null);
                    dictservice.SetValue("TableStoredProcedureMappings", null);
                }
                else
                {
                    CheckNodes();
                }
            }

            base.OnActivated();
        }

        public override bool IsDataValid
        {
            get
            {
                bool response = false;

                if(this.tables != null)
                {
                    response = (this.tables.Count > 0);
                }

                return response;
            }
        }

        private void trvDatabase_Leave(object sender, EventArgs e)
        {
            SaveArgument();
        }

        private void trvDatabase_MouseLeave(object sender, EventArgs e)
        {
            SaveArgument();
        }
        #endregion

        #region Private Implementation
        private void CheckNodes()
        {
            IDictionaryService dictservice = (IDictionaryService)GetService(typeof(IDictionaryService));
            this.tables = (ArrayList)dictservice.GetValue("Tables");

            if(this.tables != null)
            {
                if(tables.Count > 0)
                {
                    foreach(TreeNode node in trvDatabase.Nodes[0].Nodes)
                    {
                        if(node.Text == "Tables")
                        {
                            foreach(TreeNode objectNode in node.Nodes)
                            {
                                SD.Table tableTemp = (SD.Table)objectNode.Tag;

                                objectNode.Checked = TableExists(tableTemp.Name);
                            }
                        }
                    }
                }
            }
        }

        private bool TableExists(string tableName)
        {
            if(this.tables != null)
            {
                foreach(SD.Table table in this.tables)
                {
                    if(table.Name == tableName)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        private void RenderNodes()
        {
            Cursor.Current = Cursors.WaitCursor;

            try
            {
                IDictionaryService dictionary = (IDictionaryService)GetService(typeof(IDictionaryService));
                ConnectionStringSettings connectionSettings = (ConnectionStringSettings)dictionary.GetValue("ConnectionSettings");

                trvDatabase.Nodes.Clear();
                trvDatabase.Nodes.Add(new DataBaseNode(connectionSettings.Name));

                TreeNode tableNode = NodesHelper.GetTableNodes(connectionSettings, false);

                if(tableNode != null)
                {
                    trvDatabase.Nodes[0].Nodes.Add(tableNode);
                }

                trvDatabase.Nodes[0].Expand();
            }
            catch
            {
                IUIService uiService = (IUIService)GetService(typeof(IUIService));

                uiService.ShowMessage(Microsoft.Practices.RepositoryFactory.Properties.Resources.ErrorObtainingMetadata);
            }

            Cursor.Current = Cursors.Default;
        }

        private ArrayList GetSelectedTables()
        {
            ArrayList selectedTables = new ArrayList();

            foreach(TreeNode node in trvDatabase.Nodes[0].Nodes)
            {
                if(node.Text == "Tables")
                {
                    foreach(TreeNode objectNode in node.Nodes)
                    {
                        if(objectNode.Checked)
                        {
                            selectedTables.Add((SD.Table)objectNode.Tag);
                        }
                    }
                }
            }

            return selectedTables;
        }

        private void SaveArgument()
        {
            tables = GetSelectedTables();
            IDictionaryService dictservice = (IDictionaryService)GetService(typeof(IDictionaryService));
            dictservice.SetValue("Tables", tables);
        }
        #endregion
    }
}